// optional standard header
// Copyright (c) Microsoft Corporation. All rights reserved.
#pragma once
#ifndef _OPTIONAL_
#define _OPTIONAL_
#ifndef RC_INVOKED
#include <initializer_list>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include <xmemory0>
#include <xsmf_control.h>

#if !_HAS_CXX17
 #error class template optional is only available with C++17.
#endif /* _HAS_CXX17 */

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,_STL_WARNING_LEVEL)
 #pragma warning(disable: _STL_DISABLED_WARNINGS)
 #pragma push_macro("new")
 #undef new

_STD_BEGIN

		// STRUCT nullopt_t [optional.nullopt]
struct nullopt_t
	{	// no-value state indicator
	struct _Tag {};
	constexpr explicit nullopt_t(_Tag) {}
	};
/* inline */ constexpr nullopt_t nullopt{nullopt_t::_Tag{}};

		// CLASS bad_optional_access [optional.bad_optional_access]
class bad_optional_access
	: public logic_error
	{
public:
	bad_optional_access()
		: logic_error("Bad optional access")
		{}

 #if _HAS_EXCEPTIONS

 #else /* _HAS_EXCEPTIONS */
protected:
	virtual void _Doraise() const
		{	// perform class-specific exception handling
		_RAISE(*this);
		}
 #endif /* _HAS_EXCEPTIONS */
	};

template<class _Ty,
	bool = is_trivially_destructible<_Ty>::value>
	struct _Optional_destruct_base;

template<class _Ty>
	struct _Optional_destruct_base<_Ty, true>
	{	// either contains a value of _Ty or is empty (trivial destructor)
	union
		{
		char _Dummy;
		_Ty _Value;
		};
	bool _Has_value;

	constexpr _Optional_destruct_base() _NOEXCEPT
		: _Dummy{}, _Has_value{false}
		{	// initialize an empty optional
		}

	template<class... _Types>
		constexpr explicit _Optional_destruct_base(in_place_t, _Types&&... _Args)
		: _Value(_STD forward<_Types>(_Args)...), _Has_value{true}
		{	// initialize contained value with _Args...
		}

#if 1 // TRANSITION, VSO#255357
	_Optional_destruct_base(const _Optional_destruct_base&) = default;
	_Optional_destruct_base(_Optional_destruct_base&&) = default;
	_Optional_destruct_base& operator=(const _Optional_destruct_base&) = default;
	_Optional_destruct_base& operator=(_Optional_destruct_base&&) = default;
#endif // TRANSITION, VSO#255357
	};

template<class _Ty>
	struct _Optional_destruct_base<_Ty, false>
	{	// either contains a value of _Ty or is empty (nontrivial destructor)
	union
		{
		char _Dummy;
		_Ty _Value;
		};
	bool _Has_value;

	~_Optional_destruct_base() _NOEXCEPT
		{	// destroy any contained value
		if (_Has_value)
			{
			_Destroy_in_place(_Value);
			}
		}

	constexpr _Optional_destruct_base() _NOEXCEPT
		: _Dummy{}, _Has_value{false}
		{	// initialize an empty optional
		}

	template<class... _Types>
		constexpr explicit _Optional_destruct_base(in_place_t, _Types&&... _Args)
		: _Value(_STD forward<_Types>(_Args)...), _Has_value{true}
		{	// initialize contained value with _Args...
		}
	};

template<class _Ty>
	struct _Optional_construct_base
		: _Optional_destruct_base<_Ty>
	{	// Layer common behaviors atop the _Optional_destruct_base implementations
	using _Optional_destruct_base<_Ty>::_Optional_destruct_base;

	template<class... _Types>
		void _Construct(_Types&&... _Args)
		{	// transition from the empty to the value-containing state
		// Pre: !this->_Has_value
		_Construct_in_place(this->_Value, _STD forward<_Types>(_Args)...);
		this->_Has_value = true;
		}

	template<class _Ty2>
		void _Assign(_Ty2&& _Right)
		{	// assign / initialize the contained value from _Right
		if (this->_Has_value)
			{
			this->_Value = _STD forward<_Ty2>(_Right);
			}
		else
			{
			_Construct(_STD forward<_Ty2>(_Right));
			}
		}

	void reset() _NOEXCEPT
		{	// destroy any contained value and transition to the empty state
		if (this->_Has_value)
			{
			_Destroy_in_place(this->_Value);
			this->_Has_value = false;
			}
		}
	};

template<class _Ty,
	bool = is_trivially_copyable<_Ty>::value>
	struct _Optional_copymove_base;

template<class _Ty>
	struct _Optional_copymove_base<_Ty, true>
		: _Optional_construct_base<_Ty>
	{	// _Ty is trivially copyable: use defaulted (trivial) special member functions
	using _Optional_construct_base<_Ty>::_Optional_construct_base;
	};

template<class _Ty>
	struct _Optional_copymove_base<_Ty, false>
		: _Optional_construct_base<_Ty>
	{	// _Ty is not trivially copyable: implement special member functions
	using _Optional_construct_base<_Ty>::_Optional_construct_base;

	_Optional_copymove_base() = default;

	_Optional_copymove_base(const _Optional_copymove_base& _Right)
		{	// initialize contained value from _Right iff it contains a value
		if (_Right._Has_value)
			{
			this->_Construct(_Right._Value);
			}
		}

	_Optional_copymove_base(_Optional_copymove_base&& _Right)
		_NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value)
		{	// initialize contained value from _Right iff it contains a value
		if (_Right._Has_value)
			{
			this->_Construct(_STD move(_Right._Value));
			}
		}

	_Optional_copymove_base& operator=(const _Optional_copymove_base& _Right)
		{	// assign/initialize/destroy contained value from _Right
		if (_Right._Has_value)
			{
			this->_Assign(_Right._Value);
			}
		else
			{
			this->reset();
			}
		return (*this);
		}

	_Optional_copymove_base& operator=(_Optional_copymove_base&& _Right)
		_NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value
			&& is_nothrow_move_assignable<_Ty>::value)
		{	// assign/initialize/destroy contained value from _Right
		if (_Right._Has_value)
			{
			this->_Assign(_STD move(_Right._Value));
			}
		else
			{
			this->reset();
			}
		return (*this);
		}
	};

		// CLASS TEMPLATE optional [optional.object]
template<class _Ty>
	class __declspec(empty_bases) optional
		: private _Optional_copymove_base<_Ty>,
		private _SMF_control_copy<is_copy_constructible<_Ty>::value>,
		private _SMF_control_move<is_move_constructible<_Ty>::value>,
		private _SMF_control_copy_assign<is_copy_constructible<_Ty>::value && is_copy_assignable<_Ty>::value>,
		private _SMF_control_move_assign<is_move_constructible<_Ty>::value && is_move_assignable<_Ty>::value>
	{	// optional for object types
public:
	static_assert(!is_reference<_Ty>::value,
		"T in optional<T> cannot be a reference type (N4606 [optional.syn]/1).");
	static_assert(!is_same<remove_cv_t<_Ty>, nullopt_t>::value,
		"T in optional<T> cannot be nullopt_t (N4606 [optional.syn]/1).");
	static_assert(!is_same<remove_cv_t<_Ty>, in_place_t>::value,
		"T in optional<T> cannot be in_place_t (N4606 [optional.syn]/1).");
	static_assert(is_reference<_Ty>::value || is_object<_Ty>::value,
		"T in optional<T> must be an object type (N4606 [optional.object]/3).");
	static_assert(is_destructible<_Ty>::value && !is_array<_Ty>::value,
		"T in optional<T> must satisfy the requirements of Destructible (N4606 [optional.object]/3).");

	using value_type = _Ty;

	// constructors [optional.object.ctor]
	constexpr optional() _NOEXCEPT
		: _Optional_copymove_base<_Ty>{}
		{	// initialize to empty state
		}
	constexpr optional(nullopt_t) _NOEXCEPT
		: _Optional_copymove_base<_Ty>{}
		{	// initialize to empty state
		}

	template<class... _Types,
		class = enable_if_t<is_constructible<_Ty, _Types...>::value>>
		constexpr explicit optional(in_place_t, _Types&&... _Args)
		: _Optional_copymove_base<_Ty>(in_place, _STD forward<_Types>(_Args)...)
		{	// initialize contained value from _Args...
		}

	template<class _Elem,
		class... _Types,
		class = enable_if_t<is_constructible<_Ty, initializer_list<_Elem>&, _Types...>::value>>
		constexpr explicit optional(in_place_t, initializer_list<_Elem> _Ilist, _Types&&... _Args)
		: _Optional_copymove_base<_Ty>(in_place, _Ilist, _STD forward<_Types>(_Args)...)
		{	// initialize contained value from _Ilist and _Args...
		}

	template<class _Ty2>
		using _AllowDirectConversion = bool_constant<
			!is_same<_Ty2, in_place_t>::value
			&& !is_same<optional, decay_t<_Ty2>>::value
			&& is_constructible<_Ty, _Ty2>::value>;
	template<class _Ty2 = _Ty,
		enable_if_t<conjunction<_AllowDirectConversion<_Ty2>, is_convertible<_Ty2, _Ty>>::value, int> = 0>
		constexpr optional(_Ty2&& _Right)
		: _Optional_copymove_base<_Ty>(in_place, _STD forward<_Ty2>(_Right))
		{	// initialize contained value from _Right
		}
	template<class _Ty2 = _Ty,
		enable_if_t<conjunction<_AllowDirectConversion<_Ty2>, negation<is_convertible<_Ty2, _Ty>>>::value, int> = 0>
		constexpr explicit optional(_Ty2&& _Right)
		: _Optional_copymove_base<_Ty>(in_place, _STD forward<_Ty2>(_Right))
		{	// initialize contained value from _Right
		}

	template<class _Ty2>
		struct _AllowUnwrapping
			: bool_constant<
				!(is_constructible_v<_Ty, optional<_Ty2>&>
				|| is_constructible_v<_Ty, const optional<_Ty2>&>
				|| is_constructible_v<_Ty, const optional<_Ty2>>
				|| is_constructible_v<_Ty, optional<_Ty2>>
				|| is_convertible_v<optional<_Ty2>&, _Ty>
				|| is_convertible_v<const optional<_Ty2>&, _Ty>
				|| is_convertible_v<const optional<_Ty2>, _Ty>
				|| is_convertible_v<optional<_Ty2>, _Ty>)>
			{};

	template<class _Ty2,
		enable_if_t<conjunction<
			is_constructible<_Ty, const _Ty2&>,
			_AllowUnwrapping<_Ty2>,
			is_convertible<const _Ty2&, _Ty>>::value, int> = 0>
		optional(const optional<_Ty2>& _Right)
		{	// possibly initialize contained value from _Right
		if (_Right)
			{
			this->_Construct(*_Right);
			}
		}
	template<class _Ty2,
		enable_if_t<conjunction<
			is_constructible<_Ty, const _Ty2&>,
			_AllowUnwrapping<_Ty2>,
			negation<is_convertible<const _Ty2&, _Ty>>>::value, int> = 0>
		explicit optional(const optional<_Ty2>& _Right)
		{	// possibly initialize contained value from _Right
		if (_Right)
			{
			this->_Construct(*_Right);
			}
		}

	template<class _Ty2,
		enable_if_t<conjunction<
			is_constructible<_Ty, _Ty2>,
			_AllowUnwrapping<_Ty2>,
			is_convertible<_Ty2, _Ty>>::value, int> = 0>
		optional(optional<_Ty2>&& _Right)
		{	// possibly initialize contained value from _Right
		if (_Right)
			{
			this->_Construct(_STD move(*_Right));
			}
		}
	template<class _Ty2,
		enable_if_t<conjunction<
			is_constructible<_Ty, _Ty2>,
			_AllowUnwrapping<_Ty2>,
			negation<is_convertible<_Ty2, _Ty>>>::value, int> = 0>
		explicit optional(optional<_Ty2>&& _Right)
		{	// possibly initialize contained value from _Right
		if (_Right)
			{
			this->_Construct(_STD move(*_Right));
			}
		}

	// assignment [optional.object.assign]
	optional& operator=(nullopt_t) _NOEXCEPT
		{	// destroy any contained value and transition to empty state
		reset();
		return (*this);
		}

	template<class _Ty2 = _Ty,
		class = enable_if_t<conjunction<
			bool_constant<
				!is_same<optional, decay_t<_Ty2>>::value
				&& !(is_scalar<_Ty>::value && is_same<_Ty, decay_t<_Ty2>>::value)>,
			is_constructible<_Ty, _Ty2>,
			is_assignable<_Ty&, _Ty2>>::value>>
		optional& operator=(_Ty2&& _Right)
		{	// assign/initialize contained value from _Right
		this->_Assign(_STD forward<_Ty2>(_Right));
		return (*this);
		}

	template<class _Ty2>
		struct _AllowUnwrappingAssignment
			: bool_constant<
				!(is_assignable_v<_Ty&, optional<_Ty2>&>
				|| is_assignable_v<_Ty&, const optional<_Ty2>&>
				|| is_assignable_v<_Ty&, const optional<_Ty2>>
				|| is_assignable_v<_Ty&, optional<_Ty2>>)>
			{};

	template<class _Ty2,
		class = enable_if_t<conjunction<
			is_constructible<_Ty, const _Ty2&>,
			is_assignable<_Ty&, const _Ty2&>,
			_AllowUnwrappingAssignment<_Ty2>>::value>>
		optional& operator=(const optional<_Ty2>& _Right)
		{	// assign/initialize/destroy contained value from _Right
		if (_Right)
			{
			this->_Assign(*_Right);
			}
		else
			{
			reset();
			}
		return (*this);
		}

	template<class _Ty2,
		class = enable_if_t<conjunction<
			is_constructible<_Ty, _Ty2>,
			is_assignable<_Ty&, _Ty2>,
			_AllowUnwrappingAssignment<_Ty2>>::value>>
		optional& operator=(optional<_Ty2>&& _Right)
		{	// assign/initialize/destroy contained value from _Right
		if (_Right)
			{
			this->_Assign(_STD move(*_Right));
			}
		else
			{
			reset();
			}
		return (*this);
		}

	template<class... _Types>
		void emplace(_Types&&... _Args)
		{	// destroy any contained value, then initialize from _Args...
		reset();
		this->_Construct(_STD forward<_Types>(_Args)...);
		}

	template<class _Elem,
		class... _Types,
		class = enable_if_t<is_constructible<
			_Ty, initializer_list<_Elem>&, _Types...>::value>>
		void emplace(initializer_list<_Elem> _Ilist, _Types&&... _Args)
		{	// destroy any contained value, then initialize from _Ilist and _Args...
		reset();
		this->_Construct(_Ilist, _STD forward<_Types>(_Args)...);
		}

	// swap [optional.object.swap]
	void swap(optional& _Right)
		_NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value && is_nothrow_swappable<_Ty>::value)
		{	// exchange state with _Right
		static_assert(is_move_constructible<_Ty>::value,
			"optional<T>::swap requires T to be move constructible (N4606 [optional.object.swap]/1).");
		static_assert(is_swappable<_Ty>::value,
			"optional<T>::swap requires T to be swappable (N4606 [optional.object.swap]/1).");
		const bool _Engaged = has_value();
		if (_Engaged == _Right.has_value())
			{
			if (_Engaged)
				{
				_Swap_adl(**this, *_Right);
				}
			}
		else
			{
				optional& _Source = *this ? *this : _Right;
				optional& _Target = *this ? _Right : *this;
				_Target._Construct(_STD move(*_Source));
				_Source.reset();
			}
		}

	// observers [optional.object.observe]
	constexpr const _Ty * operator->() const
		{	// return pointer to contained value
		return (_STD addressof(this->_Value));
		}
	_CONSTEXPR14 _Ty * operator->()
		{	// return pointer to contained value
		return (_STD addressof(this->_Value));
		}

	constexpr const _Ty& operator*() const &
		{	// return reference to contained value
		return (this->_Value);
		}
	_CONSTEXPR14 _Ty& operator*() &
		{	// return reference to contained value
		return (this->_Value);
		}
	_CONSTEXPR14 _Ty&& operator*() &&
		{	// return reference to contained value
		return (_STD move(this->_Value));
		}
	constexpr const _Ty&& operator*() const &&
		{	// return reference to contained value
		return (_STD move(this->_Value));
		}

	constexpr explicit operator bool() const _NOEXCEPT
		{	// return true iff *this contains a value
		return (this->_Has_value);
		}
	constexpr bool has_value() const _NOEXCEPT
		{	// return true iff *this contains a value
		return (this->_Has_value);
		}

	constexpr const _Ty& value() const &
		{	// return reference to contained value or throw if none
		return ((void)(has_value() || (_THROW_NCEE(bad_optional_access, _EMPTY_ARGUMENT), true)), **this);
		}
	_CONSTEXPR14 _Ty& value() &
		{	// return reference to contained value or throw if none
		return ((void)(has_value() || (_THROW_NCEE(bad_optional_access, _EMPTY_ARGUMENT), true)), **this);
		}
	_CONSTEXPR14 _Ty&& value() &&
		{	// return reference to contained value or throw if none
		return ((void)(has_value() || (_THROW_NCEE(bad_optional_access, _EMPTY_ARGUMENT), true)), _STD move(**this));
		}
	constexpr const _Ty&& value() const &&
		{	// return reference to contained value or throw if none
		return ((void)(has_value() || (_THROW_NCEE(bad_optional_access, _EMPTY_ARGUMENT), true)), _STD move(**this));
		}

	template<class _Ty2>
		constexpr _Ty value_or(_Ty2&& _Right) const &
		{	// return contained value or _Right if none
		static_assert(is_copy_constructible<_Ty>::value,
			"The const overload of optional<T>::value_or requires T to be copy constructible "
			"(N4606 [optional.object.observe]).");
		static_assert(is_convertible<_Ty2, _Ty>::value,
			"optional<T>::value_or(U) requires U to be convertible to T (N4606 [optional.object.observe]).");
		return (*this ? **this : static_cast<_Ty>(_STD forward<_Ty2>(_Right)));
		}
	template<class _Ty2>
		_CONSTEXPR14 _Ty value_or(_Ty2&& _Right) &&
		{	// return contained value or _Right if none
		static_assert(is_move_constructible<_Ty>::value,
			"The rvalue overload of optional<T>::value_or requires T to be move constructible "
			"(N4606 [optional.object.observe]).");
		static_assert(is_convertible<_Ty2, _Ty>::value,
			"optional<T>::value_or(U) requires U to be convertible to T (N4606 [optional.object.observe]).");
		return (*this ? _STD move(**this) : static_cast<_Ty>(_STD forward<_Ty2>(_Right)));
		}

	// modifiers [optional.object.mod]
	using _Optional_copymove_base<_Ty>::reset;
	};

		// RELATIONAL OPERATORS [optional.relops]
template<class _Ty>
	constexpr bool operator==(const optional<_Ty>& _Left, const optional<_Ty>& _Right)
	{
	return (_Left.has_value() == _Right.has_value() && (!_Left || *_Left == *_Right));
	}
template<class _Ty>
	constexpr bool operator!=(const optional<_Ty>& _Left, const optional<_Ty>& _Right)
	{
	return (_Left.has_value() != _Right.has_value() || (_Left && *_Left != *_Right));
	}
template<class _Ty>
	constexpr bool operator<(const optional<_Ty>& _Left, const optional<_Ty>& _Right)
	{
	return (_Right && (!_Left || *_Left < *_Right));
	}
template<class _Ty>
	constexpr bool operator>(const optional<_Ty>& _Left, const optional<_Ty>& _Right)
	{
	return (_Left && (!_Right || *_Left > *_Right));
	}
template<class _Ty>
	constexpr bool operator<=(const optional<_Ty>& _Left, const optional<_Ty>& _Right)
	{
	return (!_Left || (_Right && *_Left <= *_Right));
	}
template<class _Ty>
	constexpr bool operator>=(const optional<_Ty>& _Left, const optional<_Ty>& _Right)
	{
	return (!_Right || (_Left && *_Left >= *_Right));
	}

		// COMPARISONS WITH nullopt [optional.nullops]
template<class _Ty>
	constexpr bool operator==(const optional<_Ty>& _Left, nullopt_t) _NOEXCEPT
	{
	return (!_Left.has_value());
	}
template<class _Ty>
	constexpr bool operator==(nullopt_t, const optional<_Ty>& _Right) _NOEXCEPT
	{
	return (!_Right.has_value());
	}

template<class _Ty>
	constexpr bool operator!=(const optional<_Ty>& _Left, nullopt_t) _NOEXCEPT
	{
	return (_Left.has_value());
	}
template<class _Ty>
	constexpr bool operator!=(nullopt_t, const optional<_Ty>& _Right) _NOEXCEPT
	{
	return (_Right.has_value());
	}

template<class _Ty>
	constexpr bool operator<(const optional<_Ty>&, nullopt_t) _NOEXCEPT
	{
	return (false);
	}
template<class _Ty>
	constexpr bool operator<(nullopt_t, const optional<_Ty>& _Right) _NOEXCEPT
	{
	return (_Right.has_value());
	}

template<class _Ty>
	constexpr bool operator<=(const optional<_Ty>& _Left, nullopt_t) _NOEXCEPT
	{
	return (!_Left.has_value());
	}
template<class _Ty>
	constexpr bool operator<=(nullopt_t, const optional<_Ty>&) _NOEXCEPT
	{
	return (true);
	}

template<class _Ty>
	constexpr bool operator>(const optional<_Ty>& _Left, nullopt_t) _NOEXCEPT
	{
	return (_Left.has_value());
	}
template<class _Ty>
	constexpr bool operator>(nullopt_t, const optional<_Ty>&) _NOEXCEPT
	{
	return (false);
	}

template<class _Ty>
	constexpr bool operator>=(const optional<_Ty>&, nullopt_t) _NOEXCEPT
	{
	return (true);
	}
template<class _Ty>
	constexpr bool operator>=(nullopt_t, const optional<_Ty>& _Right) _NOEXCEPT
	{
	return (!_Right.has_value());
	}

		// COMPARISONS WITH T [optional.comp_with_t]
template<class _Ty>
	constexpr bool operator==(const optional<_Ty>& _Left, const _Ty& _Right)
	{
	return (_Left ? *_Left == _Right : false);
	}
template<class _Ty>
	constexpr bool operator==(const _Ty& _Left, const optional<_Ty>& _Right)
	{
	return (_Right ? _Left == *_Right : false);
	}

template<class _Ty>
	constexpr bool operator!=(const optional<_Ty>& _Left, const _Ty& _Right)
	{
	return (_Left ? *_Left != _Right : true);
	}
template<class _Ty>
	constexpr bool operator!=(const _Ty& _Left, const optional<_Ty>& _Right)
	{
	return (_Right ? _Left != *_Right : true);
	}

template<class _Ty>
	constexpr bool operator<(const optional<_Ty>& _Left, const _Ty& _Right)
	{
	return (_Left ? *_Left < _Right : true);
	}
template<class _Ty>
	constexpr bool operator<(const _Ty& _Left, const optional<_Ty>& _Right)
	{
	return (_Right ? _Left < *_Right : false);
	}

template<class _Ty>
	constexpr bool operator<=(const optional<_Ty>& _Left, const _Ty& _Right)
	{
	return (_Left ? *_Left <= _Right : true);
	}
template<class _Ty>
	constexpr bool operator<=(const _Ty& _Left, const optional<_Ty>& _Right)
	{
	return (_Right ? _Left <= *_Right : false);
	}

template<class _Ty>
	constexpr bool operator>(const optional<_Ty>& _Left, const _Ty& _Right)
	{
	return (_Left ? *_Left > _Right : false);
	}
template<class _Ty>
	constexpr bool operator>(const _Ty& _Left, const optional<_Ty>& _Right)
	{
	return (_Right ? _Left > *_Right : true);
	}

template<class _Ty>
	constexpr bool operator>=(const optional<_Ty>& _Left, const _Ty& _Right)
	{
	return (_Left ? *_Left >= _Right : false);
	}
template<class _Ty>
	constexpr bool operator>=(const _Ty& _Left, const optional<_Ty>& _Right)
	{
	return (_Right ? _Left >= *_Right : true);
	}

		// FUNCTION TEMPLATE swap [optional.specalg]
template<class _Ty,
	class = enable_if_t<is_move_constructible<_Ty>::value && is_swappable<_Ty>::value>> inline
	void swap(optional<_Ty>& _Left, optional<_Ty>& _Right)
		_NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right)))
	{	// exchange the values of _Left and _Right
	_Left.swap(_Right);
	}

		// FUNCTION TEMPLATE make_optional [optional.specalg]
template<class _Ty>
	constexpr optional<decay_t<_Ty>> make_optional(_Ty&& _Value)
	{	// Construct an optional from _Value
	return (optional<decay_t<_Ty>>{_STD forward<_Ty>(_Value)});
	}
template<class _Ty,
	class... _Types>
	constexpr optional<_Ty> make_optional(_Types&&... _Args)
	{	// Construct an optional from _Args
	return (optional<_Ty>{in_place, _STD forward<_Types>(_Args)...});
	}
template<class _Ty,
	class _Elem,
	class... _Types>
	constexpr optional<_Ty> make_optional(initializer_list<_Elem> _Ilist, _Types&&... _Args)
	{	// Construct an optional from _Ilist and _Args
	return (optional<_Ty>{in_place, _Ilist, _STD forward<_Types>(_Args)...});
	}

		// STRUCT TEMPLATE SPECIALIZATION hash [optional.hash]
template<class _Ty>
	struct hash<optional<_Ty>>
	{	// hash functor for optional<_Ty>
	size_t operator()(const optional<_Ty>& _Opt) const
		{
		constexpr size_t _Unspecified_value = 0;
		return (_Opt ? hash<_Ty>{}(*_Opt) : _Unspecified_value);
		}
	};

_STD_END

 #pragma pop_macro("new")
 #pragma warning(pop)
 #pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _OPTIONAL_ */
